package com.walleipt.ipt_tools.utils;

import java.awt.Dimension;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

public class ConvertUtils {

	public static String toString(Object _obj) {
		if (_obj == null)
			return "";
		else {
			Class<?> clz = _obj.getClass();

			if (clz.isArray()) {
				StringBuffer buffer = new StringBuffer();
				Object[] objs = (Object[]) _obj;
				for (int i = 0; i < objs.length; i++) {
					if (objs[i] != null)
						buffer.append(toString(objs[i]));
				}

				return buffer.toString();
			} else if (_obj instanceof Collection) {
				StringBuffer buffer = new StringBuffer();
				Iterator<?> iter = ((Collection<?>) _obj).iterator();
				while (iter.hasNext()) {
					Object obj = iter.next();
					if (obj != null)
						buffer.append(toString(obj));
				}

				return buffer.toString();
			} else if (_obj instanceof Date)
				return DateUtils.dateToStr((Date) _obj);
			else if (_obj instanceof Timestamp)
				return DateUtils.dateToStr(new Date(((Timestamp) _obj)
						.getTime()));
			else
				return _obj.toString();
		}
	}

	public static int toInt(byte _byte) {
		int temp = (int) _byte;
		if (temp < 0)
			temp += 256;
		return temp;
	}

	public static int toInt(byte[] _bytes) {
		if (_bytes == null)
			return 0;
		else {
			int length = _bytes.length > 4 ? 4 : _bytes.length;
			int temp = 0;

			for (int i = 0; i < length - 1; i++) {
				if (_bytes[i] > 0)
					temp = temp + _bytes[i];
				else
					temp = temp + 256 + _bytes[i];
				temp = temp * 256;
			}

			if (_bytes[length - 1] > 0)
				temp = temp + _bytes[length - 1];
			else

				temp = temp + 256 + _bytes[length - 1];

			return temp;
		}
	}

	public static int toInt(String _data) {
		try {
			if (_data == null || _data.length() <= 0)
				return -1;
			return Integer.parseInt(_data);
		} catch (Exception err) {
			return -1;
		}
	}

	public static int toInt(Number _number) {
		try
		{
			if ( _number == null )
				return -1 ;
			return _number.intValue() ;
		}
		catch( Exception err )
		{
			return -1 ;
		}
	}	
	
	public static long toLong(String _data) {
		try {
			if (_data == null || _data.length() <= 0)
				return -1;
			return Long.parseLong(_data);
		} catch (Exception err) {
			return -1;
		}
	}
	
	public static long toLong(Number _number) {
		try {
			if (_number == null)
				return -1;
			return _number.longValue() ;
		} catch (Exception err) {
			return -1;
		}
	}

	public static double toDouble(String _data) {
		try {
			if (_data == null || _data.length() <= 0)
				return -1;
			return Double.parseDouble(_data);
		} catch (Exception err) {
			return -1;
		}
	}
	
	public static double toDouble(Number _number) {
		try {
			if (_number == null)
				return -1;
			return _number.doubleValue() ;
		} catch (Exception err) {
			return -1;
		}
	}
	

	public static float toFloat(String _data) {
		try {
			if (_data == null || _data.length() <= 0)
				return 0;
			return Float.parseFloat(_data);
		} catch (Exception err) {
			return 0;
		}
	}
	public static double toFloat(Number _number) {
		try {
			if (_number == null)
				return -1;
			return _number.floatValue();
		} catch (Exception err) {
			return -1;
		}
	}

	public static byte[] toBytes(String _data, int _fixLength) {
		if (_fixLength > 0) {
			byte[] bytes = new byte[_fixLength];
			for (int i = 0; i < _fixLength; i++)
				bytes[i] = 0x0;
			byte[] temp = _data.getBytes();
			System.arraycopy(temp, 0, bytes, 0,
					(_fixLength <= temp.length) ? _fixLength : temp.length);
			return bytes;
		} else
			return _data.getBytes();
	}

	public static boolean toBoolean(String _data) {
		if (_data == null)
			return false;

		char firstChar = Character.toLowerCase(_data.charAt(0));
		if ('1' == firstChar || 't' == firstChar || 'y' == firstChar)
			return true;
		else
			return false;
	}

	public static Dimension toDimension(String _data) {
		Dimension dimension = new Dimension();
		String[] fields = StringUtils.split((String) _data, "*");
		if (fields == null || fields.length == 0)
			return dimension;
		if (fields.length == 1) {
			if (fields[0].contains("."))
				dimension.setSize(Double.parseDouble(fields[0].trim()),
						Double.MAX_VALUE);
			else
				dimension.setSize(Integer.parseInt(fields[0].trim()),
						Integer.MAX_VALUE);
		} else {
			if (fields[0].contains(".") || fields[1].contains("."))
				dimension.setSize(
						fields[0] == null ? 0 : Double.parseDouble(fields[0]
								.trim()), Double.parseDouble(fields[1].trim()));
			else
				dimension.setSize(
						fields[0] == null ? 0 : Integer.parseInt(fields[0]
								.trim()), Integer.parseInt(fields[1].trim()));
		}

		return dimension;
	}

	public static List<Integer> toList(String[] _arr) {
		List<Integer> list = new ArrayList<Integer>();

		if (_arr == null)
			return null;

		for (String str : _arr) {
			if (ConvertUtils.toInt(str) >= 0)
				list.add(ConvertUtils.toInt(str));
		}

		return list;
	}

	public static List<Integer> toList(String str, String separator) {
		String[] arr = StringUtils.split(str, separator);
		return toList(arr);
	}
	
	public static List<String> toListStr(String values, String separator) {
		if (StringUtils.isEmpty(values))
			return null;
		String[] arr = StringUtils.split(values, separator);
		List<String> results = new ArrayList<String>(arr.length);
		for (String str : arr) {
			results.add(str);
		}
		return results;
	}
	
	public static List<Short> toListForShort(String _str, String _separator) {
		List<Short> list = new ArrayList<Short>();

		String[] arr = StringUtils.split(_str, _separator);

		if (arr == null)
			return null;

		for (String str : arr) {
			if (ConvertUtils.toInt(str) >= 0)
				list.add((short) ConvertUtils.toInt(str));
		}

		return list.size() != arr.length ? null : list;
	}

	public static List<Integer> toList(List<?> _list, String field) {
		List<Integer> result = new ArrayList<Integer>();

		for (Object object : _list) {
			try {
				String val = BeanUtils.getProperty(object, field);
				result.add(ConvertUtils.toInt(val));
			} catch (IllegalAccessException e) {
				return result == null ? new ArrayList<Integer>() : result;
			} catch (InvocationTargetException e) {
				return result == null ? new ArrayList<Integer>() : result;
			} catch (NoSuchMethodException e) {
				return result == null ? new ArrayList<Integer>() : result;
			}

		}

		return result == null ? new ArrayList<Integer>() : result;
	}

	public static String list2Str(List<Integer> _list, String separator) {
		String result = "";
		for (Integer integer : _list) {
			result = result + integer + separator;
		}

		return result.substring(0, result.length() - separator.length());
	}
	
	public static String list2Str_(List<String> _list, String separator) {
		String result = "";
		for (String string : _list) {
			result = result + string + separator;
		}

		return result.substring(0, result.length() - separator.length());
	}

	public static String list2Str(List<?> _list, String field, String separator) {
		String result = "";
		for (Object obj : _list) {
			try {
				String val = BeanUtils.getProperty(obj, field);
				if (org.apache.commons.lang3.StringUtils.isEmpty(val))
					continue;
				result += val + ",";
			} catch (IllegalAccessException e) {
			} catch (InvocationTargetException e) {
			} catch (NoSuchMethodException e) {
			}
		}

		return result.substring(0, result.length() - separator.length());
	}

	public static <T> T map2Bean(Map<String, Object> map, Class<T> c) {
		if (map == null)
			return null;

		T t = null;
		try {
			t = c.newInstance();
		} catch (InstantiationException | IllegalAccessException e1) {
			e1.printStackTrace();
		}
		if (t == null)
			return null;

		try {
			BeanUtils.populate(t, map);
		} catch (Exception e) {
			System.out.println("transMap2Bean2 Error " + e);
			t = null;
		}

		return t;
	}
	
	/***
     * 将对象转换为map对象
     * @param thisObj 对象
     * @return
     */
    @SuppressWarnings("rawtypes")
	public static Map<String,Object> toMap(Object thisObj)
    {
        Map<String,Object> map = new HashMap<>();
        Class c;
        try
        {
            c = Class.forName(thisObj.getClass().getName());
            //获取所有的方法
            Method[] m = c.getMethods();
            for (int i = 0; i < m.length; i++)
            {   //获取方法名
                String method = m[i].getName();
                //获取get开始的方法名
                if (method.startsWith("get")&&!method.contains("getClass"))
                {
                    try{
                        //获取对应对应get方法的value值
                        Object value = m[i].invoke(thisObj);
                        if (value != null)
                        {
                            //截取get方法除get意外的字符 如getUserName-->UserName
                            String key=method.substring(3);
                            //将属性的第一个值转为小写
                            key=key.substring(0,1).toLowerCase()+key.substring(1);
                            //将属性key,value放入对象
                            map.put(key, value);
                        }
                    }catch (Exception e) {
                        // TODO: handle exception
                        System.out.println("error:"+method);
                    }
                }
            }
        }
        catch (Exception e)
        {
            // TODO: handle exception
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 将Map对象通过反射机制转换成Bean对象
     *
     * @param map 存放数据的map对象
     * @param clazz 待转换的class
     * @return 转换后的Bean对象
     * @throws Exception 异常
     */
    public static Object toObject(Map<String, Object> map, Class<?> clazz) throws Exception {
        Object obj = clazz.newInstance();
        if(map != null && map.size() > 0) {
            for(Map.Entry<String, Object> entry : map.entrySet()) {
                String propertyName = entry.getKey();       //属性名
                Object value = entry.getValue();
                String setMethodName = "set"
                        + propertyName.substring(0, 1).toUpperCase()
                        + propertyName.substring(1);
                //获取属性对应的对象字段
                Field field = getClassField(clazz, propertyName);
                if(field==null)
                    continue;
                //获取字段类型
                Class<?> fieldTypeClass = field.getType();
                //根据字段类型进行值的转换
                value = convertValType(value, fieldTypeClass);
                try{
                    //调用对象对应的set方法
                    clazz.getMethod(setMethodName, field.getType()).invoke(obj, value);
                }catch(NoSuchMethodException e){
                    e.printStackTrace();
                }
            }
        }
        return obj;
    }

    /**
     * 获取指定字段名称查找在class中的对应的Field对象(包括查找父类)
     *
     * @param clazz 指定的class
     * @param fieldName 字段名称
     * @return Field对象
     */
    private static Field getClassField(Class<?> clazz, String fieldName) {
        if( Object.class.getName().equals(clazz.getName())) {
            return null;
        }
        Field []declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().equals(fieldName)) {
                return field;
            }
        }

        Class<?> superClass = clazz.getSuperclass();
        if(superClass != null) {// 简单的递归一下
            return getClassField(superClass, fieldName);
        }
        return null;
    }

    /**
     * 将Object类型的值，转换成bean对象属性里对应的类型值
     *
     * @param value Object对象值
     * @param fieldTypeClass 属性的类型
     * @return 转换后的值
     */
    private static Object convertValType(Object value, Class<?> fieldTypeClass) {
        Object retVal = null;
        if(Long.class.getName().equals(fieldTypeClass.getName())
                || long.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Long.parseLong(value.toString());
        } else if(Integer.class.getName().equals(fieldTypeClass.getName())
                || int.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Integer.parseInt(value.toString());
        } else if(Float.class.getName().equals(fieldTypeClass.getName())
                || float.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Float.parseFloat(value.toString());
        } else if(Double.class.getName().equals(fieldTypeClass.getName())
                || double.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Double.parseDouble(value.toString());
        } else {
            retVal = value;
        }
        return retVal;
    }

}
